package top.chukongxiang.monitorservice.javafx.fxml;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import lombok.extern.slf4j.Slf4j;
import top.chukongxiang.monitorservice.config.ApplicationStatusContextHolder;
import top.chukongxiang.monitorservice.javafx.core.FxContextHolder;
import top.chukongxiang.monitorservice.model.constant.ConfigKeyConstant;
import top.chukongxiang.monitorservice.tools.FxBeanUtil;
import top.chukongxiang.monitorservice.tools.H2Util;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;

/**
 * @author 楚孔响
 * @version 1.0
 * @date 2023/10/19 13:26
 */
@Slf4j
public class SettingGui implements Initializable {

    public static final String KEY = "settings";

    @FXML
    private Label serverStatusLabel;

    @FXML
    private TextField sdkFolderTextField;

    @FXML
    private TextField serverPortTextField;

    @FXML
    private CheckBox serverAutoRunCheckBox;

    @FXML
    private Button saveButton;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        ApplicationStatusContextHolder.registerListener((observable, oldValue, newValue) -> {
            String label = newValue.getLabel();
            Platform.runLater(() -> serverStatusLabel.setText(label));
        });
    }

    public static void show() {
        Platform.runLater(()->{
            try {
                Stage stage = FxContextHolder.get(KEY);
                if (stage == null) {
                    stage = new Stage();
                    FXMLLoader fxmlLoader = new FXMLLoader(SettingGui.class.getClassLoader().getResource("fxml/settings.fxml"));
                    Parent pane = fxmlLoader.load();
                    Scene scene = new Scene(pane);
                    stage.setScene(scene);
                    stage.setTitle("设置");
                    // 使用系统风格窗口，标题栏
                    stage.initStyle(StageStyle.DECORATED);
                    // 禁用窗口的最大化功能
                    stage.setResizable(false);
                    // 存放Scene
                    FxContextHolder.set(KEY, stage, fxmlLoader.getNamespace());
                }
                loadData();
                stage.show();
            } catch (IOException e) {
                log.error(e.getMessage(), e);
                throw new RuntimeException(e);
            }
        });
    }

    private static void loadData() {
        Label serverStatusLabel = FxContextHolder.getNode(KEY, "serverStatusLabel");
        if (serverStatusLabel != null) {
            serverStatusLabel.setText(ApplicationStatusContextHolder.getCurrentStatus().getLabel());
        }

        String hkSdkFolder = H2Util.getConfigValue(ConfigKeyConstant.HK_SDK_FOLDER);
        TextField sdkFolderTextField = FxContextHolder.getNode(KEY, "sdkFolderTextField");
        if (StrUtil.isNotBlank(hkSdkFolder) && sdkFolderTextField != null) {
            sdkFolderTextField.setText(hkSdkFolder);
        }

        String serverPort = H2Util.getConfigValue(ConfigKeyConstant.SERVER_PORT);
        TextField serverPortTextField = FxContextHolder.getNode(KEY, "serverPortTextField");
        if (StrUtil.isNotBlank(serverPort) && serverPortTextField != null) {
            serverPortTextField.setText(serverPort);
        }

        String autoStart = H2Util.getConfigValue(ConfigKeyConstant.AUTO_START);
        boolean selected = BooleanUtil.toBoolean(autoStart);
        CheckBox serverAutoRunCheckBox = FxContextHolder.getNode(KEY, "serverAutoRunCheckBox");
        if (serverAutoRunCheckBox != null) {
            serverAutoRunCheckBox.setSelected(selected);
        }
    }

    @FXML
    public void chooseFolder(ActionEvent event) {
        Platform.runLater(() -> {
            DirectoryChooser directoryChooser = new DirectoryChooser();
            Stage stage = FxContextHolder.get(KEY);
            File file = directoryChooser.showDialog(stage);
            if (file != null) {
                try {
                    sdkFolderTextField.setText(file.getCanonicalPath());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    @FXML
    public void saveClick(ActionEvent event) {
        // 校验
        String sdkFolder = sdkFolderTextField.getText();
        if (!FileUtil.exist(sdkFolder)) {
            showConfigureErrorAlert("海康SDK文件夹不存在，请确认路径是否正确");
            return;
        }
        String serverPortText = serverPortTextField.getText();
        if (StrUtil.isBlank(serverPortText) || !NumberUtil.isNumber(serverPortText) || serverPortText.length() > 5) {
            showConfigureErrorAlert("服务端口格式错误！");
            return;
        }
        int serverPort = Integer.parseInt(serverPortText);
        if (serverPort > 65535 || serverPort < 0) {
            showConfigureErrorAlert("服务端口格式错误！");
            return;
        }
        saveButton.setDisable(true);
        saveButton.setText("保存中");
        Platform.runLater(() -> {
            // 校验通过，开始保存
            H2Util.setConfig(ConfigKeyConstant.HK_SDK_FOLDER, sdkFolder);
            H2Util.setConfig(ConfigKeyConstant.SERVER_PORT, serverPortText);
            H2Util.setConfig(ConfigKeyConstant.AUTO_START, serverAutoRunCheckBox.isSelected());
            saveButton.setDisable(false);
            saveButton.setText("保存");
            FxBeanUtil.updateSdkFolder();
            // 关闭窗口
            close();
        });

    }

    public void showConfigureErrorAlert(String msg) {
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setTitle("错误");
        alert.setHeaderText("配置错误");
        alert.setContentText(msg);
        alert.initOwner(FxContextHolder.get(KEY));
        alert.showAndWait();
    }

    public void close() {
        Stage stage = FxContextHolder.get(KEY);
        stage.close();
    }

}
